package com.demo9;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.file.FileResult;
import com.github.unidbg.file.IOResolver;
import com.github.unidbg.file.linux.AndroidFileIO;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.api.AssetManager;
import com.github.unidbg.linux.android.dvm.array.ArrayObject;
import com.github.unidbg.linux.android.dvm.wrapper.DvmBoolean;
import com.github.unidbg.linux.android.dvm.wrapper.DvmInteger;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.spi.SyscallHandler;
import com.github.unidbg.virtualmodule.android.AndroidModule;
import com.github.unidbg.virtualmodule.android.JniGraphics;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Ks extends AbstractJni implements IOResolver {
    @Override
    public FileResult resolve(Emulator emulator, String pathname, int oflags) {
        System.out.println("file open:"+pathname);
        return null;
    }

    private final AndroidEmulator emulator;
    private final VM vm;
    private final DvmClass JNICLibrary;

    Ks() {
        // 创建模拟器实例
        emulator = AndroidEmulatorBuilder.for32Bit().build();

        // 模拟器的内存操作接口
        final Memory memory = emulator.getMemory();
        // 设置系统类库解析
        memory.setLibraryResolver(new AndroidResolver(23));
        // 创建Android虚拟机
        vm = emulator.createDalvikVM(new File("unidbg-android/src/test/resources/demo9/ks910.apk"));
        new JniGraphics(emulator, vm).register(memory);
        new AndroidModule(emulator, vm).register(memory);

        vm.setJni(this);
        vm.setVerbose(true);

        emulator.getSyscallHandler().addIOResolver(this);

        DalvikModule dm = vm.loadLibrary("kwsgmain", true);

        // 执行JNIOnLoad（如果有的话）
        dm.callJNI_OnLoad(emulator);
        JNICLibrary = vm.resolveClass("com/kuaishou/android/security/internal/dispatch/JNICLibrary");
    }

    public void callinit(){
        DvmObject<?> context = vm.resolveClass("com/yxcorp/gifshow/App").newObject(null); // context
        ArrayObject arrayObject = new ArrayObject(null, new StringObject(vm, "d7b7d042-d4f2-4012-be60-d97ff2429c17"),null,null,context,null,null);
        JNICLibrary.newObject(null).callJniMethodObject(emulator, "doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;", 10412, arrayObject);
    }

    public void callTarget(){
        DvmObject<?> context = vm.resolveClass("com/yxcorp/gifshow/App").newObject(null); // context
        StringObject urlObj = new StringObject(vm, "/rest/n/feed/selectionbb9caf23ee1fda57a6c167198aba919f");
        ArrayObject urlArrayObj = new ArrayObject(urlObj);
        StringObject appkey = new StringObject(vm,"d7b7d042-d4f2-4012-be60-d97ff2429c17");
        DvmInteger intergetobj = DvmInteger.valueOf(vm, -1);
        DvmBoolean boolobj = DvmBoolean.valueOf(vm, false);
        ArrayObject arrayObject = new ArrayObject(urlArrayObj, appkey,intergetobj,boolobj,context,null,boolobj);
        String result = JNICLibrary.newObject(null).callJniMethodObject(emulator, "doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;", 10418, arrayObject).getValue().toString();
        System.out.println("result:"+result);
    }

    public static void main(String[] args) {
        Ks ks = new Ks();
        ks.callinit();
        ks.callTarget();
    }

    @Override
    public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
        switch (signature){
            case "com/yxcorp/gifshow/App->getPackageCodePath()Ljava/lang/String;":{
                return new StringObject(vm, "/data/app/com.smile.gifmaker-oyRnT1esU1Pf5iDY6JKtjA==/base.apk");
            }
            case "com/yxcorp/gifshow/App->getAssets()Landroid/content/res/AssetManager;":{
                return new AssetManager(vm, signature);
            }
            case "com/yxcorp/gifshow/App->getPackageName()Ljava/lang/String;":{
                return new StringObject(vm, "com.smile.gifmaker");
            }
            case "com/yxcorp/gifshow/App->getPackageManager()Landroid/content/pm/PackageManager;":{
                return vm.resolveClass("android/content/pm/PackageManager").newObject(null);
            }
        }
        return super.callObjectMethodV(vm, dvmObject, signature, vaList);
    }

    @Override
    public void callStaticVoidMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
        switch (signature){
            case "com/kuaishou/android/security/internal/common/ExceptionProxy->nativeReport(ILjava/lang/String;)V":{
                return;
            }
        }
        super.callStaticVoidMethodV(vm, dvmClass, signature, vaList);
    }


    @Override
    public boolean callBooleanMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
        switch (signature){
            case "java/lang/Boolean->booleanValue()Z":{
                return (boolean) dvmObject.getValue();
            }
        }
        return super.callBooleanMethodV(vm, dvmObject, signature, vaList);
    }
}
